package xyz.scootaloo.kami.cloud.service

import io.vertx.core.Future
import xyz.scootaloo.kami.cloud.lang.*
import xyz.scootaloo.kami.cloud.model.po.CacheEntry
import xyz.scootaloo.kami.cloud.model.po.CacheUpdateExpiry
import xyz.scootaloo.kami.cloud.service.impl.CacheServiceImpl

/**
 * 为了保证性能和系统的简洁性, 只支持存储字符串键值对;
 * 要存储其他类型, 请使用json, 并自行处理序列化问题
 *
 * 在内部api[InternalCacheServiceApi]中, 存在两个方法[InternalCacheServiceApi.get]和[InternalCacheServiceApi.put],
 * 可以存取任意对象, 但是这两个方法都不允许在外部访问,
 *
 * @author flutterdash@qq.com
 * @since 2022/4/10 21:18
 */
@Public
interface CacheService : SingletonCrontab {

    override fun crontab(): CrontabService.Crontab

    fun put(key: String, value: String, ex: Long = DEF_EXPIRY_TIME): Future<Unit>

    fun get(key: String): Future<String?>

    fun delete(key: String): Future<Unit>

    fun updateExpiryTime(key: String, newExpiryTime: Long): Future<Unit>

    @InternalApi
    fun internal(): InternalCacheServiceApi

    @EventbusConsumerApi(Constant.EB_CACHE_PREFIX)
    interface InternalCacheServiceApi {
        @EventbusConsumerApi(Constant.EB_CACHE_PUT, CacheEntry::class)
        fun put(key: String, value: Any, ex: Long = DEF_EXPIRY_TIME)

        @EventbusConsumerApi(Constant.EB_CACHE_GET, String::class)
        fun <T> get(key: String): T?

        @EventbusConsumerApi(Constant.EB_CACHE_DEL, String::class)
        fun delete(key: String)

        @EventbusConsumerApi(Constant.EB_CACHE_UpEx, CacheUpdateExpiry::class)
        fun updateExpiryTime(key: String, newExpiryTime: Long)
    }

    companion object {
        const val DEF_EXPIRY_TIME = 5000L
        const val INVALID_EX_TIME = 0L

        operator fun invoke(): CacheService {
            return CacheServiceImpl
        }
    }
}